package basics.iconcurrent.lock;

import basics.iconcurrent.IThreadFactory;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.LongAdder;

/**
 * @author or2
 * @Description 自旋锁 演示 - 自加器 基础原子类 计数比较
 * @create 2021年09月14日 时间: 8:59
 */
public class SpinLock {
    private final AtomicReference<Thread> sign = new AtomicReference<>();

    public void lock() {
        AtomicInteger atomicInteger = new AtomicInteger();
        LongAdder adder = new LongAdder();
        while (!sign.compareAndSet(null, Thread.currentThread())) {
            atomicInteger.getAndIncrement();
            adder.increment();
        }
        System.out.println("自旋次数: " + atomicInteger.get());
        System.out.println("自旋次数: " + adder);
    }

    public void unlock() {
        sign.compareAndSet(Thread.currentThread(), null);
    }

    public static void main(String[] args) {
        SpinLock spinLock = new SpinLock();
        ExecutorService executorService = Executors.newFixedThreadPool(2, new IThreadFactory("读写锁"));
        for (int i = 0; i < 2; i++) {
            executorService.submit((Callable<Void>) () -> {
                System.out.println(Thread.currentThread().getName() + " 尝试获取锁");
                spinLock.lock();
                System.out.println(Thread.currentThread().getName() + " +获取到锁");
                Thread.sleep(300);
                spinLock.unlock();
                return null;
            });
        }
        executorService.shutdown();
    }
}
